using System.Runtime.Serialization.Formatters;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PathMap //: MonoBehaviour
{


    bool isFindPath;//是否找到路径
    List<PathData> newPathList = new List<PathData>();//新寻找到的路径点列表，加入到开表中排序
    List<PathData> openPathList = new List<PathData>(); //开表
    List<PathData> closePathList = new List<PathData>(); //闭表

    PathData[,] pathArray;

    // 行列距离
    float hangValue;
    float lieValue;

    PathData boxPathData;//交换排序容器

    PathData TargetPathData;//寻路中的承接路径 
    int numberOfSteps; //步骤
    bool isMove;//是否允许移动
    Stack<int[]> pathStack = new Stack<int[]>();//最终路径

    public Stack<int[]> PathStack { get => pathStack; set => pathStack = value; }
    public PathData[,] PathArray { get => pathArray; set => pathArray = value; }

    public PathMap()
    {
        PathArray = new PathData[0, 0];
        UpdateMapData();//初始化角色寻路点地图信息
    }
    public void UpdateMapData()//更新路径地图
    {
        //判断寻路地图与地形地图的尺寸是否相等
        if (MapContorller.GetInstance().ArrayGrid.GetLength(0) != PathArray.GetLength(0) || MapContorller.GetInstance().ArrayGrid.GetLength(1) != PathArray.GetLength(1))
        {
            PathArray = new PathData[MapContorller.GetInstance().ArrayGrid.GetLength(0), MapContorller.GetInstance().ArrayGrid.GetLength(1)];
            for (int i = 0; i < MapContorller.GetInstance().ArrayGrid.GetLength(0); i++)
            {
                for (int j = 0; j < MapContorller.GetInstance().ArrayGrid.GetLength(1); j++)
                {
                    PathArray[i, j] = new PathData();
                    PathArray[i, j].father = new PathData();
                    PathArray[i, j].pathCy = new int[2];
                    PathArray[i, j].pathCy[0] = i;
                    PathArray[i, j].pathCy[1] = j;
                    PathArray[i, j].name = i.ToString() + "*" + j.ToString();
                }
            }
        }
        else
        {
            for (int i = 0; i < MapContorller.GetInstance().ArrayGrid.GetLength(0); i++)
            {
                for (int j = 0; j < MapContorller.GetInstance().ArrayGrid.GetLength(1); j++)
                {
                    if (MapContorller.GetInstance().ArrayGrid[i, j].E_Grid_Type == E_MapGrid_Type.Type_obstacle)
                    {
                        PathArray[i, j].PathType = E_PathGrid_Type.Type_obstacle;
                    }
                    else
                    {
                        PathArray[i, j].PathType = E_PathGrid_Type.Type_default;
                    }
                }
            }
        }
        // foreach (var item in PathArray)
        // {
        //     Debug.Log($"{item.name}");
        // }
    }

    public Stack<int[]> SetStartAndEndPath(int[] start, int[] end) //设置起点终点
    {
        PathArray[start[0], start[1]].PathType = E_PathGrid_Type.Type_startPath;
        PathArray[start[0], start[1]].father = null;
        PathArray[end[0], end[1]].PathType = E_PathGrid_Type.Type_endPath;
        LookForPath(PathArray[start[0], start[1]], PathArray[end[0], end[1]]);
        return PathStack;
    }

    void LookForPath(PathData startGrid, PathData endGrid)//开始寻路
    {
        //SetStartAndEndPath(startGrid.pathCy, endGrid.pathCy);
        isFindPath = false;
        if (!isFindPath)
        {
            for (int i = startGrid.pathCy[0] - 1; i < startGrid.pathCy[0] + 2; i++)//y
            {
                if (i >= 0 && i < PathArray.GetLength(0))
                {
                    for (int j = startGrid.pathCy[1] - 1; j < startGrid.pathCy[1] + 2; j++)
                    {
                        if (j >= 0 && j < PathArray.GetLength(1))
                        {
                            if (PathArray[i, j].PathType == E_PathGrid_Type.Type_default || PathArray[i, j].PathType == E_PathGrid_Type.Type_endPath)
                            {
                                if (PathArray[i, j].PathType == E_PathGrid_Type.Type_endPath) //判断路径是否是终点路径
                                {

                                }
                                else
                                {
                                    PathArray[i, j].PathType = E_PathGrid_Type.Type_passPaht;
                                }
                                PathArray[i, j].father = startGrid;
                                newPathList.Add(PathArray[i, j]);
                            }
                        }
                    }
                }
            }
            //计算消耗
            for (int i = 0; i < newPathList.Count; i++)
            {
                //子到父消耗
                if (newPathList[i].pathCy[0] == startGrid.pathCy[0] || newPathList[i].pathCy[1] == startGrid.pathCy[1])
                {
                    newPathList[i].fatherToMeCost = 1;
                }
                else
                {
                    newPathList[i].fatherToMeCost = 1.4f;
                }
                //子到起消耗 = 子到父+父消耗
                if (newPathList[i].father.PathType == E_PathGrid_Type.Type_endPath)
                {
                    newPathList[i].toStartCost = newPathList[i].fatherToMeCost;
                }
                else
                {
                    newPathList[i].toStartCost = newPathList[i].father.toStartCost + newPathList[i].fatherToMeCost;
                }
                //总消耗
                if (newPathList[i].pathCy[0] > endGrid.pathCy[0])
                {
                    hangValue = newPathList[i].pathCy[0] - endGrid.pathCy[0];
                }
                else
                {
                    hangValue = endGrid.pathCy[0] - newPathList[i].pathCy[0];
                }
                if (newPathList[i].pathCy[1] > endGrid.pathCy[1])
                {
                    lieValue = newPathList[i].pathCy[1] - endGrid.pathCy[1];
                }
                else
                {
                    lieValue = endGrid.pathCy[1] - newPathList[i].pathCy[1];
                }
                newPathList[i].toEndCost = hangValue + lieValue;
                newPathList[i].allCost = newPathList[i].toStartCost + newPathList[i].toEndCost;
            }
            //开列表与寻路暂存列表组合
            openPathList.AddRange(newPathList);
            newPathList.Clear();
            //排序
            for (int i = 0; i < openPathList.Count; i++)
            {
                SortForOpenPathList();
            }
            TargetPathData = openPathList[0];
            closePathList.Add(openPathList[0]);
            openPathList.RemoveAt(0);
            if (TargetPathData.PathType == E_PathGrid_Type.Type_endPath)//当前路径是否为目标路径
            {
                isFindPath = true;//找到了 停止寻路
                numberOfSteps = 0;
                GetPathList();
                Clear();
            }
            else
            {
                if (openPathList.Count <= 0)
                {
                    isFindPath = true;
                    Debug.Log("没有路");
                    Clear();
                }
                else
                {
                    ++numberOfSteps;
                    LookForPath(TargetPathData, endGrid);
                }

            }
        }
    }

    void SortForOpenPathList()  //tag：排序需要优化
    {
        for (int i = 0; i < openPathList.Count; i++)
        {
            if (i + 1 != openPathList.Count)
            {
                if (openPathList[i].allCost > openPathList[i + 1].allCost)
                {
                    boxPathData = openPathList[i];
                    openPathList[i] = openPathList[i + 1];
                    openPathList[i + 1] = boxPathData;
                }
            }
        }
    }
    void GetPathList()
    {
        pathStack.Clear();
        PathStack.Push(TargetPathData.pathCy);
        while (TargetPathData.father != null)
        {


            PathStack.Push(TargetPathData.father.pathCy);
            TargetPathData = TargetPathData.father;
        }
    }

    void Clear()
    {
        newPathList.Clear();
        openPathList.Clear();
        closePathList.Clear();
        hangValue = 0;
        lieValue = 0;
        numberOfSteps = 0;
    }
}

/// <summary>
/// 路径点类型
/// </summary>
public enum E_PathGrid_Type
{
    Type_default,
    Type_passPaht,
    Type_obstacle,
    Type_startPath,
    Type_endPath
}